package com.skyyan.netty.jjf.util;

/**
 * 默认输入都是整数
 * @author skyyan
 */
public class DeviceRegIDUtils {

    /**
     * 输入的都是整数
     * 设备注册号 转换成16个字节数组 ,低位在前 高位在后, 位数不足补0
     */
    public static byte[] convertTo16Bytes(String deviceRegID) {
        byte[] bytes = new byte[16];
        // 初始化数组为0
        for (int i = 0; i < 16; i++) {
            bytes[i] = 0;
        }

        if (deviceRegID == null || deviceRegID.isEmpty()) {
            return bytes;
        }

        // 提取字符串中的数字字符
        StringBuilder numberStr = new StringBuilder();
        for (char c : deviceRegID.toCharArray()) {
            if (Character.isDigit(c)) {
                numberStr.append(c);
            }
        }

        // 如果没有数字字符，则使用0
        if (numberStr.length() == 0) {
            return bytes;
        }

        try {
            // 将字符串转换为长整型
            long id = Long.parseLong(numberStr.toString());

            // 转换为小端序字节数组（低位在前，高位在后）
            for (int i = 0; i < 8; i++) {
                bytes[i] = (byte) (id & 0xFF);
                id = id >> 8;
            }
        } catch (NumberFormatException e) {
            // 如果数字太大，无法解析为long，则只取前几位数字
            String truncated = numberStr.substring(0, Math.min(18, numberStr.length()));
            long id = Long.parseLong(truncated);
            for (int i = 0; i < 8; i++) {
                bytes[i] = (byte) (id & 0xFF);
                id = id >> 8;
            }
        }

        return bytes;
    }

    /**
     *
     * @param bytes 低位在前 高位在后, 位数不足补0
     * @return
     */
    public static String convertToInt(byte[] bytes) {
        if (bytes == null) {
            return "0";
        }

        long id = 0;
        // 从低位开始组合成long值（小端序）
        // 最多处理8个字节，因为long是64位
        int len = Math.min(bytes.length, 8);
        for (int i = len - 1; i >= 0; i--) {
            id = (id << 8) | (bytes[i] & 0xFF);
        }

        return String.valueOf(id);
    }

    public static void main(String[] args) {
        System.out.println("=== DeviceRegIDUtils 测试 ===");

        // 测试用例1: 正常的设备注册号
        String deviceId1 = "12345";
        byte[] bytes1 = convertTo16Bytes(deviceId1);
        String result1 = convertToInt(bytes1);
        System.out.println("测试用例1:");
        System.out.println("  原始ID: " + deviceId1);
        System.out.println("  转换为字节数组: " + bytesToHex(bytes1));
        System.out.println("  转换回ID: " + result1);
        System.out.println("  结果匹配: " + deviceId1.equals(result1));
        System.out.println();

        // 测试用例2: 较大的设备注册号
        String deviceId2 = "123456789012345";
        byte[] bytes2 = convertTo16Bytes(deviceId2);
        String result2 = convertToInt(bytes2);
        System.out.println("测试用例2:");
        System.out.println("  原始ID: " + deviceId2);
        System.out.println("  转换为字节数组: " + bytesToHex(bytes2));
        System.out.println("  转换回ID: " + result2);
        System.out.println("  结果匹配: " + deviceId2.equals(result2));
        System.out.println();

        // 测试用例3: null值
        String deviceId3 = null;
        byte[] bytes3 = convertTo16Bytes(deviceId3);
        String result3 = convertToInt(bytes3);
        System.out.println("测试用例3:");
        System.out.println("  原始ID: " + deviceId3);
        System.out.println("  转换为字节数组: " + bytesToHex(bytes3));
        System.out.println("  转换回ID: " + result3);
        System.out.println();

        // 测试用例4: 空字符串
        String deviceId4 = "";
        byte[] bytes4 = convertTo16Bytes(deviceId4);
        String result4 = convertToInt(bytes4);
        System.out.println("测试用例4:");
        System.out.println("  原始ID: \"" + deviceId4 + "\"");
        System.out.println("  转换为字节数组: " + bytesToHex(bytes4));
        System.out.println("  转换回ID: " + result4);
        System.out.println();

        // 测试用例5: 验证小端序
        String deviceId5 = "255";
        byte[] bytes5 = convertTo16Bytes(deviceId5);
        System.out.println("测试用例5 (小端序验证):");
        System.out.println("  原始ID: " + deviceId5);
        System.out.println("  转换为字节数组前8位: " + bytesToHex(java.util.Arrays.copyOf(bytes5, 8)));
        System.out.println("  第一个字节(低位): 0x" + String.format("%02X", bytes5[0]));
        System.out.println();

        // 测试用例6: 包含字符的设备注册号
        String deviceId6 = "DEV12345ABC";
        byte[] bytes6 = convertTo16Bytes(deviceId6);
        String result6 = convertToInt(bytes6);
        System.out.println("测试用例6 (包含字符):");
        System.out.println("  原始ID: " + deviceId6);
        System.out.println("  提取的数字: 12345");
        System.out.println("  转换为字节数组: " + bytesToHex(bytes6));
        System.out.println("  转换回ID: " + result6);
        System.out.println("  结果匹配: " + "12345".equals(result6));
        System.out.println();

        // 测试用例7: 只包含字符的设备注册号
        String deviceId7 = "DEVICEABC";
        byte[] bytes7 = convertTo16Bytes(deviceId7);
        String result7 = convertToInt(bytes7);
        System.out.println("测试用例7 (只包含字符):");
        System.out.println("  原始ID: " + deviceId7);
        System.out.println("  提取的数字: (无)");
        System.out.println("  转换为字节数组: " + bytesToHex(bytes7));
        System.out.println("  转换回ID: " + result7);
        System.out.println("  结果匹配: " + "0".equals(result7));
        System.out.println();

        // 测试用例8: 包含特殊字符和数字的设备注册号
        String deviceId8 = "#$123#456#789!";
        byte[] bytes8 = convertTo16Bytes(deviceId8);
        String result8 = convertToInt(bytes8);
        System.out.println("测试用例8 (包含特殊字符):");
        System.out.println("  原始ID: " + deviceId8);
        System.out.println("  提取的数字: 123456789");
        System.out.println("  转换为字节数组: " + bytesToHex(bytes8));
        System.out.println("  转换回ID: " + result8);
        System.out.println("  结果匹配: " + "123456789".equals(result8));
    }

    // 辅助方法：将字节数组转换为十六进制字符串
    private static String bytesToHex(byte[] bytes) {
        if (bytes == null) return "null";
        StringBuilder sb = new StringBuilder();
        sb.append("[");
        for (int i = 0; i < bytes.length; i++) {
            if (i > 0) sb.append(" ");
            sb.append(String.format("%02X", bytes[i] & 0xFF));
        }
        sb.append("]");
        return sb.toString();
    }
}
